

#undef NO_ADDRESS

#include "boomerang.h"

class FrontEnd;
class Proc;
class UserProc;
class Prog;
class Cluster;

class Decompiler : public Watcher
{
public:
	Decompiler() : debugging(false), waiting(false) { };

	virtual void alert_decompile_debug_point(UserProc *p, const char *description);
	virtual void alert_considering(Proc *parent, Proc *p);
	virtual void alert_decompiling(UserProc *p);
	virtual void alert_new(Proc *p);
    virtual void alert_remove(Proc *p);
	virtual void alert_update_signature(Proc *p);
	bool getRtlForProc(const char *name,const char *rtl);
	const char *getSigFile(const char *name);
	const char *getClusterFile(const char *name);
	void renameProc(const char *oldName, const char *newName);
	void rereadLibSignatures();
	void getCompoundMembers(const char *name, PVOID *MemoryTable);
	void setDebugging(bool d) { debugging = d; }
	void setUseDFTA(bool d);
    void setNoDecodeChildren(bool d);

    void addEntryPoint(ADDRESS a, const char *nam);
    void removeEntryPoint(ADDRESS a);
	void changeInputFile(const char *f);
	void changeOutputPath(const char *path);
	void load();
	void decode();
	void decompile();
	void generateCode();
	void stopWaiting();
   	void loading();
	void decoding();
	void decompiling();
	void generatingCode();
	void loadCompleted();
	void decodeCompleted();
	void decompileCompleted();
	void generateCodeCompleted();
	void consideringProc(const char *parent, const char *name);
	void decompilingProc(const char *name);
	void newUserProc(const char *name, unsigned int addr);
	void newLibProc(const char *name, const char *params);
	void removeUserProc(const char *name, unsigned int addr);
	void removeLibProc(const char *name);
	void newCluster(const char *name);
	void newProcInCluster(const char *name, const char *cluster);
	void newEntrypoint(unsigned int addr, const char *name);
	void newSection(const char *name, unsigned int start, unsigned int end);

	void machineType(const char *machine);

	void debuggingPoint(const char *name, const char *description);

protected:

	bool debugging, waiting;

	FrontEnd *fe;
	Prog *prog;

	const char *filename;

	const char *procStatus(UserProc *p);
	void emitClusterAndChildren(Cluster *root);

    std::vector<ADDRESS>user_entrypoints;
};
class DecompilerThread {
public:
	DecompilerThread() : decompiler(NULL) { };

	Decompiler *getDecompiler();

protected:
    void run();
	Decompiler *decompiler;
};

